﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ShuticsEntities;

namespace ShuticsBiz
{
    public static class ControlCuestionario
    {
        public enum Estados : short
        {
            Activo = 1,
            Completo,
            EnProceso,
            Incompleto,
            SinContestar
        }

        public static Cuestionario Buscar(int idCandidato, string clave)
        {
            return Model.context.Cuestionario.Single(c => c.Clave == clave && c.Candidato.ID == idCandidato);
        }

        public static List<Candidato> BuscarCandCuestActivo(List<Candidato> candidatos)
        {
            List<Candidato> activos = new List<Candidato>();
            foreach (Candidato cand in candidatos)
            {
                if (Model.context.Cuestionario.Include("Candidato").Any(c => (c.Estado.ID == (int)Estados.Activo || c.Estado.ID == (int)Estados.EnProceso) && c.Candidato.ID.Equals(cand.ID)))
                {
                    activos.Add(cand);
                }
            }

            return activos;
        }

        public static Cuestionario ValidarEstado(Cuestionario cuestionario)
        {
            try
            {
                if ((DateTime.Now - cuestionario.Evaluacion.Fecha).Days > cuestionario.Evaluacion.TiempoMaximoIngreso)
                {
                    Estado nuevoEstado = Model.context.Estado.Single(c => c.ID == (int)Estados.SinContestar);
                    cuestionario.Estado = nuevoEstado;
                    cuestionario.FechaUltimoIngreso = DateTime.Now;

                    Model.context.SaveChanges();
                }
                else if(cuestionario.FechaInicio!=null && (DateTime.Now - cuestionario.FechaInicio).Value.Days > cuestionario.Evaluacion.TiempoMaximoFinalizacion)
                {
                    Estado nuevoEstado = Model.context.Estado.Single(c => c.ID == (int)Estados.Incompleto);
                    cuestionario.Estado = nuevoEstado;
                    cuestionario.FechaUltimoIngreso = DateTime.Now;

                    Model.context.SaveChanges();
                }

                return cuestionario;
            }
            catch(Exception)
            {
                return cuestionario;
            }
        }

        public static bool IniciarCuestionario(Cuestionario cuestionario)
        {
            try
            {
                Estado enProceso = Model.context.Estado.Single(c => c.ID.Equals((int)ControlCuestionario.Estados.EnProceso));
                cuestionario.Estado = enProceso;
                cuestionario.FechaInicio = DateTime.Now;
                cuestionario.FechaUltimoIngreso = DateTime.Now;
                cuestionario.CantidadAccesos += 1;

                Model.context.SaveChanges();
                return true;
            }
            catch(Exception)
            {
                return false;
            }
        }

        public static bool ActualizarCuestionario(Cuestionario cuestionario)
        {
            try
            {
                cuestionario.FechaUltimoIngreso = DateTime.Now;
                cuestionario.CantidadAccesos += 1;
                Model.context.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static bool AvanzarCuestionario(Cuestionario cuestionario)
        {
            try
            {
                cuestionario.BloqueActivo += 1;
                Model.context.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static List<CuestionarioPregunta> ObtenerBloquePreguntas(Cuestionario cuestionario)
        {
            List<CuestionarioPregunta> preguntasBloque = new List<CuestionarioPregunta>();
            int cantPregXBloque = cuestionario.Evaluacion.PreguntasPorBloque;
            int bloqueActivo = cuestionario.BloqueActivo;

            for (int i = (bloqueActivo * cantPregXBloque) - cantPregXBloque; i < bloqueActivo * cantPregXBloque; i++)
            {
                try
                {
                    //Si no existen mas preguntas para el cuestionario, el metodo Single lanzara una excepcion. Al atraparla cortamos la ejecucion del bucle
                    preguntasBloque.Add(cuestionario.Preguntas.Single(c => c.Orden == i));
                }
                catch (Exception)
                {
                    break;
                }
            }

            return preguntasBloque;
        }

        public static List<Cuestionario> ObtenerCuestionariosByEvaluaciones(List<Evaluacion> evaluaciones)
        {
            List<Cuestionario> cuestionarios = new List<Cuestionario>();
            foreach (Evaluacion eval in evaluaciones)
            {
                cuestionarios.AddRange(Model.context.Cuestionario.Where(c => c.Evaluacion.ID==eval.ID).ToList());
            }
            return cuestionarios;
        }

        public static bool FinalizarCuestionario(Cuestionario cuestionario)
        {
            try
            {
                cuestionario.FechaFin = DateTime.Now;

                CalcularPuntaje(cuestionario);

                Estado completo = Model.context.Estado.Single(c => c.ID.Equals((int)ControlCuestionario.Estados.Completo));
                cuestionario.Estado = completo;

                Model.context.SaveChanges();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        private static bool CalcularPuntaje(Cuestionario cuestionario)
        {
            try
            {
                int cantidadPreguntas = 5, cantidadCompetencias = 0, cantidadFactores;
                Double? total = 0;
                bool ordenDeMerito = true;

                foreach (CuestionarioCompetencia competencia in cuestionario.Competencias)
                {
                    competencia.PuntajeObtenido = 0;

                    cantidadFactores = 0;

                    foreach (CuestionarioFactor factor in competencia.Factores)
                    {
                        foreach (CuestionarioPregunta pregunta in factor.Preguntas)
                        {
                            foreach (CuestionarioItem item in pregunta.Items)
                            {
                                competencia.PuntajeObtenido += (item.Puntaje) * (item.Seleccionado ? 1 : 0);
                            }
                        }

                        cantidadFactores++;
                    }

                    competencia.PuntajeObtenido /= (cantidadFactores * cantidadPreguntas);

                    if (ordenDeMerito)
                    {
                        ordenDeMerito = competencia.PuntajeObtenido >= competencia.Ponderacion;
                    }

                    total += competencia.PuntajeObtenido;
                    cantidadCompetencias++;
                }

                cuestionario.PuntajeObtenido = Math.Truncate(((double)total / (double)cantidadCompetencias) * 100) / 100;
                cuestionario.OrdenDeMerito = ordenDeMerito;

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}
